use std::io::SeekFrom;
use std::path::{Path, PathBuf};
+use semver::Version;
use tempdir::TempDir;
use toml;
let map = SourceConfigMap::new(config)?;
let (pkg, source) = if source_id.is_git() {
select_pkg(GitSource::new(source_id, config), source_id,
- krate, vers, &mut |git| git.read_packages())?
+ krate, vers, config, &mut |git| git.read_packages())?
} else if source_id.is_path() {
let path = source_id.url().to_file_path().ok()
.expect("path sources must have a valid path");
specify an alternate source", path.display()))
})?;
select_pkg(PathSource::new(&path, source_id, config),
- source_id, krate, vers,
+ source_id, krate, vers, config,
&mut |path| path.read_packages())?
} else {
select_pkg(map.load(source_id)?,
- source_id, krate, vers,
+ source_id, krate, vers, config,
&mut |_| Err(human("must specify a crate to install from \
crates.io, or use --path or --git to \
specify alternate source")))?
source_id: &SourceId,
name: Option<&str>,
vers: Option<&str>,
+ config: &Config,
list_all: &mut FnMut(&mut T) -> CargoResult<Vec<Package>>)
-> CargoResult<(Package, Box<Source + 'a>)>
where T: Source + 'a
source.update()?;
match name {
Some(name) => {
+ let vers = match vers {
+ Some(v) => {
+ match v.parse::<Version>() {
+ Ok(v) => Some(format!("={}", v)),
+ Err(_) => {
+ let msg = format!("the `--vers` provided, `{}`, is \
+ not a valid semver version\n\n\
+ historically Cargo treated this \
+ as a semver version requirement \
+ accidentally\nand will continue \
+ to do so, but this behavior \
+ will be removed eventually", v);
+ config.shell().warn(&msg)?;
+ Some(v.to_string())
+ }
+ }
+ }
+ None => None,
+ };
+ let vers = vers.as_ref().map(|s| &**s);
let dep = Dependency::parse_no_deprecated(name, vers, source_id)?;
let deps = source.query(&dep)?;
match deps.iter().map(|p| p.package_id()).max() {
assert_that(cargo_process("install").arg("foo").arg("--vers=0.2.0"),
execs().with_status(101).with_stderr("\
[UPDATING] registry [..]
-[ERROR] could not find `foo` in `registry [..]` with version `0.2.0`
+[ERROR] could not find `foo` in `registry [..]` with version `=0.2.0`
"));
}
let lock2 = p.read_lockfile();
assert!(lock == lock2, "different lockfiles");
}
+
+#[test]
+fn vers_precise() {
+ pkg("foo", "0.1.1");
+ pkg("foo", "0.1.2");
+
+ assert_that(cargo_process("install").arg("foo").arg("--vers").arg("0.1.1"),
+ execs().with_status(0).with_stderr_contains("\
+[DOWNLOADING] foo v0.1.1 (registry [..])
+"));
+}
+
+#[test]
+fn legacy_version_requirement() {
+ pkg("foo", "0.1.1");
+
+ assert_that(cargo_process("install").arg("foo").arg("--vers").arg("0.1"),
+ execs().with_status(0).with_stderr_contains("\
+warning: the `--vers` provided, `0.1`, is not a valid semver version
+
+historically Cargo treated this as a semver version requirement accidentally
+and will continue to do so, but this behavior will be removed eventually
+"));
+}